using System;
using NUnit.Framework;
using Rhino.Mocks;

namespace GettingStartedWithRhinoMocks
{
    [TestFixture]
    public class CustomerServiceTestFixture
    {
        [Test]
        public void Will_Write_To_Log_If_Customer_Fails_Validation_When_Adding_Customer()
        {
            // Arrange
            ICustomerValidator customerValidator = new CustomerValidator();
            TestLogger testLogger = new TestLogger();

            var customerService = new CustomerService(customerValidator, testLogger);

            var customerWithNoNameThatWillFailVaidation = new Customer();

            //Act
            customerService.AddCustomer(customerWithNoNameThatWillFailVaidation);

            //Assert
            Assert.That(testLogger.Messages.Count, Is.EqualTo(1));
        }

        [Test]
        public void Will_Write_To_Log_If_Customer_Fails_Validation_When_Adding_Customer_Using_Stub()
        {
            // Arrange
            ICustomerValidator customerValidator = MockRepository.GenerateStub<ICustomerValidator>();
            var testLogger = new TestLogger();

            var customerService = new CustomerService(customerValidator, testLogger);

            customerValidator.Stub(c => c.IsValid(null))
                .IgnoreArguments() // Use this because the argument is not important 
                .Throw(new ArgumentException(CustomerValidator.CUSTOMER_NAME_ERROR_MESSAGE));  // This will simulate the throwing of an exception

            //Act
            customerService.AddCustomer(new Customer());

            //Assert
            Assert.That(testLogger.Messages.Count, Is.EqualTo(1));
        }

        [Test]
        public void Will_Write_To_Log_If_Customer_Fails_Validation_When_Adding_Customer_Using_Stub_And_Mock()
        {
            // Arrange
            ICustomerValidator customerValidator = MockRepository.GenerateStub<ICustomerValidator>();
            ILogger logger = MockRepository.GenerateMock<ILogger>(); 

            var customerService = new CustomerService(customerValidator, logger);

            customerValidator.Stub(c => c.IsValid(null))
                  .IgnoreArguments() // Use this because the argument is not important 
                  .Throw(new ArgumentException(CustomerValidator.CUSTOMER_NAME_ERROR_MESSAGE));  // This will simulate the throwing of an exception

            //Act
            customerService.AddCustomer(new Customer());

            //Assert
            logger.AssertWasCalled(l => l.LogError(CustomerValidator.CUSTOMER_NAME_ERROR_MESSAGE));
        }
    }
}